package Java7_Concurrency_Cookbook.fork_join.recursive_action;

import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

/**
 * 主线程执行 pool.execute(task) 是异步的, 执行后立马去执行其他任务了.
 * Task线程通过 invokeAll() 同步的执行主任务所创建的多个子任务<br/>
 *
 * 关于 Zoom 中 invokeAll(task1, task2), 据我猜测task1, task2在执行的时候又调用 compute() 方法
 * 如果满足条件, 任务会再次被分解成小任务, 直到不满足条件
 * @author lixiangke
 * @date 2017/11/21
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        ProductListGenerator generator = new ProductListGenerator();
        List<Product> products = generator.generate(10000);
        Task task = new Task(products, 0, products.size(), 0.20);
        // 默认创建一个线程数等于计算机CPU数目的线程池
        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(task);
        do {
            // 当前正在执行任务的线程数
            System.out.printf("Main: Thread Count: %d\n", pool.getActiveThreadCount());
            // 表示一个工作者线程从另一个线程中偷得的任务的次数
            System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount());
            // 为池建立的期望的并发级别
            System.out.printf("Main: Thread Parallelism: %d\n", pool.getParallelism());
            TimeUnit.SECONDS.sleep(5);
        } while (!task.isDone());
        pool.shutdown();
        if (task.isCompletedNormally()) {
            System.out.printf("Main: The process has completed normally. \n");
        }
        for (int i = 0; i < products.size(); i++) {
            Product product = products.get(i);
            if (product.getPrice() != 12) {
                System.out.printf("Product: %s : %f\n", product.getName(), product.getPrice());
            }
        }
        System.out.printf("Main: End of the program.\n");
    }
}
